package com.service.infoEntry.service.impl;

import com.service.config.utils.*;
import com.service.infoEntry.dao.CalendarDao;
import com.service.infoEntry.dto.CalendarDto;
import com.service.infoEntry.entity.CalendarInfo;
import com.service.infoEntry.service.CalendarService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

import static com.service.config.utils.DateUtils.YYYYMMDDHHMMSS;
import static com.service.config.utils.DateUtils.YYYY_MM_DD_HH_MM_SS;
import static com.service.infoEntry.constant.Constant.INSUFFICIENT_USER_PERMISSIONS;
import static com.service.infoEntry.constant.Constant.USER_NO_AUTHORITY;

/**
 * @author ：hjl
 * @date ：Created in 2021/11/10 17:24
 * @description：
 */
@Service
public class CalendarServiceImpl implements CalendarService {
    @Resource
    private CalendarDao calendarDao;

    /**
     * 添加事件
     * @param calendarDto
     */
    @Override
    public void addEvent(CalendarDto calendarDto) {
        CalendarInfo calendarInfo = ModelMapperUtil.strictMap(calendarDto, CalendarInfo.class);
        calendarInfo.setId(IdUtil.getStringId());
        calendarInfo.setCreateTime(DateUtils.getNowDate());
        calendarInfo.setUpdateTime(DateUtils.getNowDate());
        calendarDao.addEvent(calendarInfo);
    }

    @Override
    public Result updateEvent(CalendarDto calendarDto) {
        if(calendarDto.getTheme()==null || "".equals(calendarDto.getTheme()))
        {
            return Result.failure("事件主题不能为空");
        }
        Date[] range = calendarDto.getRange();
        if (range.length!=2)
        {
            return Result.failure("时间段输入错误");
        }
        calendarDto.setStartDate(range[0]);
        calendarDto.setEndDate(range[1]);
        CalendarInfo calendarInfo = ModelMapperUtil.strictMap(calendarDto, CalendarInfo.class);
        calendarInfo.setUpdateTime(DateUtils.getNowDate());
        calendarDao.updateEvent(calendarInfo);
        return Result.ok();
    }

    @Override
    public Result deleteEvent(String eventId,String userId) {
        CalendarInfo calendarInfo=calendarDao.queryEventById(eventId);
        if(calendarInfo.getUserId()!=null && !"".equals(calendarInfo.getUserId()) && !calendarInfo.getUserId().equals(userId))
        {
            return Result.failure(USER_NO_AUTHORITY,INSUFFICIENT_USER_PERMISSIONS);
        }
        calendarDao.delEvent(eventId);
        return Result.ok();
    }

    @Override
    public List<Map<String,Object>> queryEventByDate(String teamId, Date date,String userId) {
        List<Map<String,Object>> finalList=new ArrayList<>();
        Map<String,Object> map;
        List<CalendarDto> list;

        Calendar c = Calendar.getInstance();
        c.setTime(date);
        int indexMonth=c.get(Calendar.MONTH)+1;
        int indexYear = c.get(Calendar.YEAR);

        c.set(Calendar.DAY_OF_MONTH,1);
        Date indexStartDate = c.getTime();
        c.add(Calendar.MONTH, 1);
        c.add(Calendar.SECOND, -1);
        Date indexEndDate = c.getTime();
        List<CalendarInfo> calendarInfos = calendarDao.queryEventByDate(indexStartDate,indexEndDate,indexMonth, teamId);

        for (CalendarInfo calendarInfo : calendarInfos) {
            CalendarDto calendarDto = ModelMapperUtil.strictMap(calendarInfo, CalendarDto.class);
            calendarDto.setOperation(calendarDto.getUserId().equals(userId)?true:false);

            Date[] range = calendarDto.getRange();
            range[0]=calendarDto.getStartDate();
            range[1]=calendarDto.getEndDate();

            Calendar calendar = Calendar.getInstance();
            Date startDate = calendarDto.getStartDate();
            Date endDate = calendarDto.getEndDate();
            calendar.setTime(startDate);
            int startDay = calendar.get(Calendar.DAY_OF_MONTH);
            int startMonth = calendar.get(Calendar.MONTH)+1;
            int startYear = calendar.get(Calendar.YEAR);
            calendar.setTime(endDate);
            int endDay = calendar.get(Calendar.DAY_OF_MONTH);
            int endMonth = calendar.get(Calendar.MONTH)+1;
            int endYear = calendar.get(Calendar.YEAR);


            if(indexYear<startYear || indexYear>endYear)
            {
                continue;
            }else if((indexYear==startYear && indexMonth<startMonth) || (indexYear==endYear && indexMonth>endMonth))
            {
                continue;
            }

            if(endYear==startYear)
            {
                if(endMonth>startMonth && indexMonth==startMonth)
                {
                    calendar.setTime(startDate);
                    endDay=calendar.getActualMaximum(Calendar.DATE);
                }else if(endMonth>startMonth && indexMonth==endMonth)
                {
                    startDay=1;
                }else if(endMonth==startMonth){

                }else {
                    startDay=1;
                    calendar.setTime(date);
                    endDay=calendar.getActualMaximum(Calendar.DATE);
                }
            }
            if(endYear>startYear)
            {
                if(indexYear==startYear && indexMonth==startMonth)
                {
                    calendar.setTime(startDate);
                    endDay=calendar.getActualMaximum(Calendar.DATE);
                }else if(indexYear==startYear && indexMonth==endMonth)
                {
                    startDay=1;
                    endDay=calendar.getActualMaximum(Calendar.DATE);
                }else if(indexYear==endYear && indexMonth==endMonth)
                {
                    startDay=1;
//                    endDay=calendar.getActualMaximum(Calendar.DATE);
                }else if(indexYear==endYear && indexMonth==startMonth)
                {
                    startDay=1;
                    endDay=calendar.getActualMaximum(Calendar.DATE);
                }else {
                    startDay=1;
                    calendar.setTime(date);
                    endDay=calendar.getActualMaximum(Calendar.DATE);
                }
            }

            if (endDay>startDay)
            {
                for (int i=startDay;i<endDay+1;i++)
                {
                    map=new HashMap<>();
                    list=new ArrayList<>();
                    boolean b=false;
                    int index = 0;

                    for (int j=0;j<finalList.size();j++) {
                        if (finalList.get(j).get("day").equals(i))
                        {
                            b=true;
                            index=j;
                        }
                    }
                    if(b)
                    {
                        List<CalendarDto> info = (List<CalendarDto>) finalList.get(index).get("descriptions");
                        info.add(calendarDto);
                    }else {
                        map.put("day",i);
                        list.add(calendarDto);
                        map.put("descriptions",list);
                        finalList.add(map);
                    }
                }
            }
            if(endDay==startDay)
            {
                map=new HashMap<>();
                list=new ArrayList<>();
                boolean b=false;
                int index = 0;
                for (int j=0;j<finalList.size();j++) {
                    if (finalList.get(j).get("day").equals(startDay))
                    {
                        b=true;
                        index=j;
                    }
                }
                if(b)
                {
                    List<CalendarDto> info = (List<CalendarDto>) finalList.get(index).get("descriptions");
                    info.add(calendarDto);
                }else {
                    map.put("day",startDay);
                    list.add(calendarDto);
                    map.put("descriptions",list);
                    finalList.add(map);
                }
            }
        }
        Collections.sort(finalList, new Comparator<Map<String, Object>>() {
            @Override
            public int compare(Map<String, Object> o1, Map<String, Object> o2) {
                return  ((int)o1.get("day")-(int)o2.get("day"));
            }
        });
        return finalList;
    }
}
